package com.cyj.dream.security.handler;

import com.cyj.dream.core.exception.BusinessException;
import com.cyj.dream.core.util.R;
import com.cyj.dream.security.exception.SosAuthenticationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.nio.file.AccessDeniedException;

/**
 * @Description: 接口权限判断工具
 * @BelongsProject: DreamChardonnay
 * @BelongsPackage: com.cyj.dream.security.component
 * @Author: ChenYongJia
 * @CreateTime: 2021-10-19 13:30
 * @Email: chen87647213@163.com
 * @Version: 1.0
 */
@Slf4j
@RestControllerAdvice
public class SecurityExceptionHandler {


	/**
	 * AccessDeniedException
	 * @param e the e
	 * @return R
	 */
	@ExceptionHandler(AccessDeniedException.class)
	@ResponseStatus(HttpStatus.FORBIDDEN)
	public R handleAccessDeniedException(AccessDeniedException e) {
		String msg = SpringSecurityMessageSource.getAccessor().getMessage("AbstractAccessDecisionManager.accessDenied",
				e.getMessage());
		log.error("拒绝授权异常信息 ex={}", msg, e);
		return R.failed(e.getLocalizedMessage());
	}

	@ExceptionHandler(BadCredentialsException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	private R handleBadCredentialsException(BadCredentialsException e) {
		log.error("权限校验异常 ex={}", e.getMessage(), e);
		R<Object> failed = R.failed(e.getMessage());
		failed.setCode(401);
		return failed;
	}

	@ExceptionHandler(UsernameNotFoundException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	private R handleUsernameNotFoundException(UsernameNotFoundException e) {
		log.error("权限校验异常 ex={}", e.getMessage(), e);
		R<Object> failed = R.failed(e.getMessage());
		failed.setCode(401);
		return failed;
	}

	@ExceptionHandler(SosAuthenticationException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	private R handleUsernameNotFoundException(SosAuthenticationException e) {
		log.error("权限校验异常 ex={}", e.getMessage(), e);
		R<Object> failed = R.failed(401,e.getMessage());
		if(e.getCause() instanceof BusinessException){
			BusinessException businessException=(BusinessException)e.getCause();
			failed.setCode(businessException.getCode());
		}
		return failed;
	}

}
